package com.sh.caryr.erp.controller.product;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.sh.caryr.erp.entity.PageResultMessage;
import com.sh.caryr.erp.entity.ResultMessage;
import com.sh.caryr.erp.entity.product.CombNum;
import com.sh.caryr.erp.entity.product.Product;
import com.sh.caryr.erp.entity.product.ProductSpec;
import com.sh.caryr.erp.entity.user.User;
import com.sh.caryr.erp.exception.RestServiceException;
import com.sh.caryr.erp.exception.ResultCode;
import com.sh.caryr.erp.service.IProductService;
import com.sh.caryr.erp.service.IProductSpecService;
import com.sh.caryr.erp.util.ERPConstants;
import com.sh.caryr.erp.util.MyBatisUtil;
import com.sh.caryr.erp.util.UtilityTool;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/api/product")
@SessionAttributes("user")
public class ProductController {

    private final IProductService productService;

    private final IProductSpecService productSpecService;

    @Autowired
    public ProductController(IProductService productService, IProductSpecService productSpecService) {
        this.productService = productService;
        this.productSpecService = productSpecService;
    }

    @ApiOperation(value = "获取产品总数量", notes = "获取产品数量")
    @RequestMapping(value = "/count", method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    @SuppressWarnings("unchecked")
    public ResultMessage<Integer> countProducts(@ModelAttribute("user") User operator) {
        Wrapper<Product> wrapper = MyBatisUtil.addAuthFilter(MyBatisUtil.getIsActiveWrapper(), operator, ERPConstants.AUTH_TARGET_PRODUCT, false, true);
        return new ResultMessage<>(productService.selectCount(wrapper));
    }

    @ApiOperation(value = "获取产品列表信息,支持分页，支持多个查询条件（多个条件用','隔开），支持单个排序", notes = "获取产品列表信息")
    @RequestMapping(method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    @SuppressWarnings("unchecked")
    public PageResultMessage<List<Product>> findProducts(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "20") Integer size,
            @RequestParam(required = false) String queryField,
            @RequestParam(required = false) String queryValue,
            @RequestParam(defaultValue = "id") String orderBy,
            @RequestParam(defaultValue = "false") Boolean isAsc,
            @ModelAttribute("user") User operator) {
        size = MyBatisUtil.SELECT_ALL == size || MyBatisUtil.PAGE_SIZE_MAX < size ? MyBatisUtil.PAGE_SIZE_MAX : size;
        Wrapper wrapper = MyBatisUtil.getIsActiveWrapper(queryField, queryValue, orderBy,isAsc);
        MyBatisUtil.addAuthFilter(wrapper,operator,ERPConstants.AUTH_TARGET_PRODUCT,false,true);
        List<Product> products = productService.findProductsDynamic(current, size, wrapper, orderBy);
        return new PageResultMessage<>(products, productService.selectCount(wrapper));
    }

    @ApiOperation(value = "获取单个产品信息", notes = "获取单个产品信息")
    @ApiImplicitParam(name = "id", value = "产品id", required = true, dataType = "long")
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    public ResultMessage<Product> findProductById(@PathVariable long id) {
        Product product = productService.selectById(id);
        if (product == null) {
            throw new RestServiceException(HttpStatus.NOT_FOUND, ResultCode.ENTITY_NOT_FOUND);
        }
        productService.getProductDetail(product);
        return new ResultMessage<>(product);
    }

    @ApiOperation(value = "创建产品", notes = "根据Product对象创建产品")
    @ApiImplicitParam(name = "product", value = "产品详细实体product", required = true, dataType = "Product")
    @RequestMapping(method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    public ResultMessage<String> insertProduct(@RequestBody Product product, @ModelAttribute("user") User operator) {
        product.setCreateBy(operator.getId());
        if (!ERPConstants.SYS_SUPER_USERNAME.equals(operator.getName())) {
            product.setCoco(operator.getCoco());
        }
        productService.insertProduct(product);
        return new ResultMessage<>(product.getId().toString());
    }

    @Transactional
    @ApiOperation(value = "更新产品", notes = "根据Product对象更新产品")
    @ApiImplicitParam(name = "product", value = "产品详细实体product", required = true, dataType = "Product")
    @RequestMapping(method = RequestMethod.PUT)
    @ResponseStatus(HttpStatus.OK)
    public ResultMessage<Product> updateProductById(@RequestBody Product product, @ModelAttribute("user") User operator) {
        if (!ERPConstants.SYS_SUPER_USERNAME.equals(operator.getName())) {
            product.setUpdateBy(operator.getId());
            product.setCoco(operator.getCoco());
        }
        productService.updateProduct(product);
        return new ResultMessage<>(product);
    }

    @ApiOperation(value = "批量删除产品", notes = "根据url的id来指定删除对象")
    @ApiImplicitParam(name = "ids", value = "产品IDS", required = true, dataType = "String")
    @RequestMapping(value = "/{ids}", method = RequestMethod.DELETE)
    @ResponseStatus(HttpStatus.OK)
    @SuppressWarnings("unchecked")
    public ResultMessage deleteProductById(@PathVariable String ids) {
        List<Long> list = UtilityTool.convertStringArray2LongList(ids.split(","));
        try {
            //Soft delete products
            UtilityTool.softDelete(Product.class, list, productService);
            //Soft delete product specs
            Wrapper productSpecWrap = new EntityWrapper<CombNum>().in("productId", list);
            List<ProductSpec> productSpecList = productSpecService.selectList(productSpecWrap);
            if (!productSpecList.isEmpty()) {
                List<Long> productSpecIds = new ArrayList<>();
                for (ProductSpec spec : productSpecList) {
                    productSpecIds.add(spec.getId());
                }
                UtilityTool.softDelete(ProductSpec.class, productSpecIds, productSpecService);
            }
            return new ResultMessage();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RestServiceException(ResultCode.DELETE_NOT_FOUND);
        }
    }
}
